#include "StdAfx.h"
#include "StreamReceiver.h"
#include "time.h"

StreamReceiver::StreamReceiver(void)
{
	firstWriteTime = 0;
}

StreamReceiver::~StreamReceiver(void)
{
}

ULONG STDMETHODCALLTYPE StreamReceiver::AddRef( void){return ++refCount;}

ULONG STDMETHODCALLTYPE StreamReceiver::Release( void){return --refCount;}

HRESULT STDMETHODCALLTYPE StreamReceiver::QueryInterface( 
    /* [in] */ REFIID riid,
	/* [iid_is][out] */ __RPC__deref_out void __RPC_FAR *__RPC_FAR *ppvObject)
{
	*ppvObject = this;
	AddRef();
	return S_OK;

	//return NOINTERFACE;
}




HRESULT STDMETHODCALLTYPE StreamReceiver::SetBaseStream( 
    IStream *pStream,
    REFGUID rguidFormat,
    const WAVEFORMATEX *pWaveFormatEx)
{
	return S_OK;
}

HRESULT STDMETHODCALLTYPE StreamReceiver::GetBaseStream( 
    IStream **ppStream)
{
	return S_OK;
}

HRESULT STDMETHODCALLTYPE StreamReceiver::BindToFile( 
    /*  */ 
    __in_z  LPCWSTR pszFileName,
    SPFILEMODE eMode,
    /*  */ 
    __in_opt  const GUID *pFormatId,
    /*  */ 
    __in_opt  const WAVEFORMATEX *pWaveFormatEx,
    ULONGLONG ullEventInterest){return S_OK;}

HRESULT STDMETHODCALLTYPE StreamReceiver::Close( void)
{
	return S_OK;
}

HRESULT STDMETHODCALLTYPE StreamReceiver::GetFormat( 
    __RPC__in GUID *pguidFormatId,
    __RPC__deref_in_opt WAVEFORMATEX **ppCoMemWaveFormatEx)
{
	int size = sizeof(WAVEFORMATEX);
	LPVOID pVoid = CoTaskMemAlloc(size);
	*ppCoMemWaveFormatEx = (WAVEFORMATEX*)pVoid;
	(*ppCoMemWaveFormatEx)->cbSize = cachedWaveFormat->cbSize;
	(*ppCoMemWaveFormatEx)->nAvgBytesPerSec = cachedWaveFormat->nAvgBytesPerSec;
	(*ppCoMemWaveFormatEx)->nBlockAlign = cachedWaveFormat->nBlockAlign;
	(*ppCoMemWaveFormatEx)->nChannels = cachedWaveFormat->nChannels;
	(*ppCoMemWaveFormatEx)->nSamplesPerSec = cachedWaveFormat->nSamplesPerSec;
	(*ppCoMemWaveFormatEx)->wBitsPerSample = cachedWaveFormat->wBitsPerSample;
	(*ppCoMemWaveFormatEx)->wFormatTag = cachedWaveFormat->wFormatTag;
	return S_OK;
}

/* [local] */ HRESULT STDMETHODCALLTYPE StreamReceiver::Seek( 
        /* [in] */ LARGE_INTEGER dlibMove,
        /* [in] */ DWORD dwOrigin,
        /* [out] */ ULARGE_INTEGER *plibNewPosition)
{
	return S_OK;
}
    
HRESULT STDMETHODCALLTYPE StreamReceiver::SetSize( 
    /* [in] */ ULARGE_INTEGER libNewSize)
{
	return S_OK;
}

/* [local] */ HRESULT STDMETHODCALLTYPE StreamReceiver::CopyTo( 
    /* [unique][in] */ IStream *pstm,
    /* [in] */ ULARGE_INTEGER cb,
    /* [out] */ ULARGE_INTEGER *pcbRead,
    /* [out] */ ULARGE_INTEGER *pcbWritten)
{
	return S_OK;
}

HRESULT STDMETHODCALLTYPE StreamReceiver::Commit( 
    /* [in] */ DWORD grfCommitFlags)
{
	return S_OK;
}

HRESULT STDMETHODCALLTYPE StreamReceiver::Revert( void)
{
	return S_OK;
}

HRESULT STDMETHODCALLTYPE StreamReceiver::LockRegion( 
    /* [in] */ ULARGE_INTEGER libOffset,
    /* [in] */ ULARGE_INTEGER cb,
    /* [in] */ DWORD dwLockType)
{
	return S_OK;
}

HRESULT STDMETHODCALLTYPE StreamReceiver::UnlockRegion( 
    /* [in] */ ULARGE_INTEGER libOffset,
    /* [in] */ ULARGE_INTEGER cb,
    /* [in] */ DWORD dwLockType)
{
	return S_OK;
}

HRESULT STDMETHODCALLTYPE StreamReceiver::Stat( 
    /* [out] */ __RPC__out STATSTG *pstatstg,
    /* [in] */ DWORD grfStatFlag)
{
	return S_OK;
}

HRESULT STDMETHODCALLTYPE StreamReceiver::Clone( 
    /* [out] */ __RPC__deref_out_opt IStream **ppstm)
{
	return S_OK;
}

/* [local] */ HRESULT STDMETHODCALLTYPE StreamReceiver::Read( 
    /* [length_is][size_is][out] */ void *pv,
    /* [in] */ ULONG cb,
    /* [out] */ ULONG *pcbRead)
{
	return S_OK;
}

/* [local] */ HRESULT STDMETHODCALLTYPE StreamReceiver::Write( 
    /* [size_is][in] */ const void *pv,
    /* [in] */ ULONG cb,
    /* [out] */ ULONG *pcbWritten)
{
	if(!firstWriteTime)
	{
		firstWriteTime = clock();
	}

	short* shortAr = (short*)pv;
	for(int i=0; i<cb/2; i++)
	{
		samples.push_back(shortAr[i]);
	}
	if(pcbWritten)
		*pcbWritten = cb;
	return S_OK;
}

